package resp

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gview"
	"github.com/gogf/gf/v2/util/gutil"
)

/*
@Time : 2023/6/19 21:16
@Author : 56766
@File : tplData.go
*/

type TplData struct {
	R       *ghttp.Request
	Tpl     string
	Params  gview.Params
	FuncMap gview.FuncMap
}

const BackendTplLayout string = "backend/public/layout.html"
const BackendErrorLayout string = "backend/public/error.html"
const BackendJumpLayout string = "backend/public/jump.html"

// WriteTplWithExit 按模板输出
func (resp *TplData) WriteTplWithExit(tpl string, params ...gview.Params) {
	resp.Tpl = tpl
	for _, val := range params {
		resp.Assign(val)
	}
	resp.R.Response.WriteTpl(resp.Tpl, resp.Params)
	resp.R.GetView().BindFuncMap(resp.FuncMap)
	resp.R.Response.WriteExit()
}

// WriteWithExit 该函数只有在输出主模板后用
func (resp *TplData) WriteWithExit(params ...gview.Params) {
	if resp.Tpl == "" {
		resp.WriteErrorTplExit("未选择要输出的模板")
	}
	for _, val := range params {
		resp.Assign(val)
	}
	resp.R.Response.WriteTpl(resp.Tpl, resp.Params)
	resp.R.GetView().BindFuncMap(resp.FuncMap)
	resp.R.Response.WriteExit()
}

// WriteTpl 输出页面模板附加自定义函数
func (resp *TplData) WriteTpl(tpl string, params ...gview.Params) {
	resp.Tpl = tpl
	for _, val := range params {
		resp.Assign(val)
	}
	resp.R.GetView().BindFuncMap(resp.FuncMap)
	resp.R.Response.WriteTpl(resp.Tpl, resp.Params)

}

// WriteErrorTplExit 输出页面模板附加自定义函数
func (resp *TplData) WriteErrorTplExit(msg string) {
	resp.Tpl = "backend/public/error.html"
	resp.Assign(gview.Params{
		"msg": msg,
	})
	resp.R.Response.WriteTpl(resp.Tpl, resp.Params)
	resp.R.Response.WriteExit()

}
func (resp *TplData) WriteExit() {
	resp.R.Response.WriteExit()
}

// Assign 绑定变量到模板
/**
tips: 也可以通过这个绑定对象
resp.Assign(gview.Params{
	"BuildIn": &response.AdminBuildIn{
		HttpRequest: g.RequestFromCtx(ctx),
	},
})
*/
func (resp *TplData) Assign(params gview.Params) {
	gutil.MapMerge(resp.Params, params)
}

// BindFunc 绑定全局函数，一处绑定，所有都会包含
func (resp *TplData) BindFunc(name string, fun interface{}) {
	resp.FuncMap[name] = fun
}

// ParseTplContent 对字符串格式模板进行解析输出
func (resp *TplData) ParseTplContent(templateString string, params ...gview.Params) (result string, err error) {

	for _, val := range params {
		resp.Assign(val)
	}
	resp.R.GetView().BindFuncMap(resp.FuncMap)
	result, err = resp.R.Response.ParseTplContent(templateString, resp.Params)

	return
}
func (resp *TplData) WriteContentWithExit(content string) {
	resp.R.Response.WriteExit(content)
}

// ParseTplContentWithExit 对字符串格式模板进行解析输出，然后直接结束
func (resp *TplData) ParseTplContentWithExit(templateString string, params ...gview.Params) {

	content, conErr := resp.ParseTplContent(templateString)
	if conErr != nil {
		g.Log().Error(resp.R.Context(), conErr)
		resp.WriteErrorTplExit(conErr.Error())
	}
	resp.WriteContentWithExit(content)

}

// Redirect 重定向
func (resp *TplData) Redirect(url string) {
	resp.R.Response.RedirectTo(url)
}

// WriteAuthErrorTplExit 输出页面模板附加自定义函数
func (resp *TplData) WriteAuthErrorTplExit(msg string) {
	tpl := "oauth/public/error.html"
	resp.Assign(gview.Params{
		"msg": msg,
	})
	resp.R.Response.WriteTpl(tpl, resp.Params)
	resp.R.Response.WriteExit()
}
